package com.lqfan.autoAnswerQ.controller.importQuestions;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lqfan.autoAnswerQ.model.fileType.FileType;
import com.lqfan.autoAnswerQ.model.quesBank.Question;
import com.lqfan.autoAnswerQ.service.fileType.IFileTypeService;
import com.lqfan.autoAnswerQ.service.quesBank.IQuestionService;
import com.lqfan.autoAnswerQ.service.wrongSubject.IWrongSubjectService;
import com.lqfan.autoAnswerQ.utils.ResponseMessage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件夹操作
 *
 * @author lqfan
 */
@RestController
@RequestMapping(value = "/api",produces = MediaType.APPLICATION_JSON_VALUE)
@Api(value = "针对类型的文件路径接口")
public class CURDFolderController {
    private static final String filePath = System.getProperty("user.dir");
    private static final Logger logger = LoggerFactory.getLogger(PoiWordController.class);
    @Autowired
    private IWrongSubjectService wrongSubjectService;
    @Autowired
    private IFileTypeService fileTypeService;

    @Autowired
    private IQuestionService questionService;
    /**
     * 新建文件夹
     *
     * @param folderName
     * @param fileType
     * @param userId
     * @return
     * @author lqfan
     */
    @ApiOperation(value = "新建文件夹", notes = "新建文件夹")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "folderName", value = "文件夹名字", required = true, dataType = "String"),
            @ApiImplicitParam(name = "type", value = "路径类型", required = true, dataType = "int"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "pid", value = "当前所在目录的id(顶级id为'0')", required = true, dataType = "String")
    })
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    @Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResponseMessage newFolder(@RequestParam(value = "folderName") String folderName,
                                     @RequestParam(value = "type") int fileType,
                                     @RequestParam(value = "userId") String userId,
                                     @RequestParam(value = "pid") String pid) {
        //新建文件夹
        int result = saveFolder( folderName, fileType, userId, pid);
        switch (result) {
            case 0:
                logger.info("路径类型:" + fileType + ", 新建文件夹:" + folderName + "失败");
                return ResponseMessage.fail("新建文件夹失败");
            case 1:
                logger.info("路径类型:" + fileType + ", 新建文件夹:" + folderName + "成功");
                return ResponseMessage.success("新建文件夹成功");
            default:
                logger.info("路径类型:" + fileType + ", 新建文件夹:" + folderName + "已经存在!");
                return ResponseMessage.fail("文件夹已经存在");
        }
    }


    /**
     * 删除文件或文件夹
     *
     * @param fid
     * @param userId
     * @return
     * @author lqfan
     */
    @ApiOperation(value = "删除文件或文件夹", notes = "删除文件或文件夹")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fid", value = "文件或文件夹的id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "filePath", value = "文件路劲", required = true, dataType = "String"),
    })
    @RequestMapping(value = "deleteHandle", method = RequestMethod.POST)
    @Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResponseMessage deleteHandle(@RequestParam(value = "fid") String fid,
                                        @RequestParam(value = "userId") String userId,
                                        @RequestParam(value = "filePath") String filePath) {
        //删除文件或文件夹
        int result = deleteFile(fid, userId,filePath);
        switch (result) {
            case 0:
                logger.info("文件/文件夹:" + fid + "  删除失败");
                return ResponseMessage.fail("删除失败");
            case 1:
                logger.info("文件/文件夹:" + fid + "  删除成功");
                return ResponseMessage.success("删除成功");
            default:
                return ResponseMessage.fail("删除失败");
        }
    }


    /**
     * 修改文件名或路径
     *
     * @param fid
     * @param userId
     * @return
     * @author lqfan
     */
    @ApiOperation(value = "修改文件名或路径", notes = "修改文件名或路径")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fid", value = "文件或文件夹的id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "oldFilePath", value = "旧路径", required = true, dataType = "String"),
            @ApiImplicitParam(name = "type", value = "路径类型", required = true, dataType = "int"),
            @ApiImplicitParam(name = "newFilePath", value = "修改后的路径", required = true, dataType = "String")
    })
    @RequestMapping(value = "changeHandle", method = RequestMethod.POST)
    @Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResponseMessage changeHandle(@RequestParam(value = "fid") String fid,
                                        @RequestParam(value = "userId") String userId,
                                        @RequestParam(value = "oldFilePath") String oldFilePath,
                                        @RequestParam(value = "type") int fileType,
                                        @RequestParam(value = "newFilePath") String newFilePath) {
        String oldPath = filePath + "/source/"+fileType+"/"+ userId+oldFilePath;
        String newPath = filePath + "/source/"+fileType+"/" + userId+newFilePath;
        FileType resObj = fileTypeService.getById(fid);
        resObj.setFilePath(newPath);
        FileType resObj1 = fileTypeService.getById(resObj.getPid());
        //检查上级是否从存在，存在则获取上一级的上一级作为修改后的pid
        if (resObj1 !=null){
            resObj.setPid(resObj1.getPid());
        }else {
            resObj.setPid("0");
        }
        boolean res = fileTypeService.saveOrUpdate(resObj);
        try {
            if (res && moveDataFile2Reject(oldPath,newPath)) {
                logger.info("修改文件/文件夹:"+oldPath+", 为: "+newPath+"     成功!");
                return ResponseMessage.success("修改成功");
            } else {
                logger.info("修改文件/文件夹:"+oldPath+", 为: "+newPath+"      失败!");
                return ResponseMessage.fail("修改失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseMessage.fail();
    }

    /**
     * 新建文件夹
     */
    private int saveFolder( String folderName, int fileType, String userId, String pid) {
        FileType type = new FileType();
        Question question = new Question();
        FileType f = getOnePid(userId,pid,fileType);
        String src = "";
        if (f==null){
            src = filePath + "/source/"+fileType +"/"+ userId + "/"+folderName+"/";
        }else {
            src = f.getFilePath()+folderName+"/";
        }
            String isExit = fileTypeService.selectFilePid(src);
            if (isExit==null){
                File path = new File(src);
                if (!path.exists()) {
                boolean res = path.mkdirs();
                if (res) {
                    question.setFilePath(src);
                    type.setFilePath(src);
                    question.setQuestionName(folderName);
                    question.setUserId(userId);
                    question.setDoNumber(0);
                    type.setUserId(userId);
                    type.setType(fileType);
                    type.setPid(pid);
                    fileTypeService.save(type);
                    questionService.save(question);
                    return 1;
                } else {
                    return 0;
                }
                } else {
                    return 2;
                }
            }else {
//                question.setFilePath(src);
//                question.setQuestionName(folderName);
//                question.setUserId(userId);
//                question.setDoNumber(0);
//                questionService.save(question);
                return 2;
            }


    }


    /**
     * 删除文件夹
     * @param fid
     * @param userId
     * @return
     */
    private int deleteFile(String fid, String userId ,String filePath) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("userId", userId);
        queryWrapper.eq("id", fid);
        FileType fileType = fileTypeService.getOne(queryWrapper);
        Boolean aBoolean = false;

        if(fileType!=null){
            String src = fileType.getFilePath();
            File file = new File(src);
             aBoolean = deleteAllFiles(file);

        }

        if (aBoolean) {
            fileTypeService.deleteFiles(filePath,userId);
            if (fileType.getType()==3){
                wrongSubjectService.deleteWrongPath(userId,filePath);
            }
//            questionService.remove(new QueryWrapper<Question>().eq("userId", userId).eq("filePath",fileType.getFilePath()));
//            fileTypeService.remove(new QueryWrapper<FileType>().eq("userId", userId)
//                                                                .eq("id", fid)
//                                                                .or()
//                                                                .eq("pid", fid));

            return 1;
        } else {
            return 0;
        }
    }

    /**
     * 递归删除文件目录及文件
     *
     * @param file
     */
    private Boolean deleteAllFiles(File file) {
        if (file == null) {
            return false;
        }
        //文件目录存在？（包括文件及文件夹）
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
            } else if (file.isDirectory()) {
                //接收文件夹目录下所有的文件实例
                File[] listFiles = file.listFiles();
                //文件夹为空 递归出口
                if (listFiles == null) {
                    return true;
                }
                for (File file2 : listFiles) {
                    //foreach遍历删除文件 递归
                    deleteAllFiles(file2);
                    logger.info("正在删除文件夹 " + file.getAbsolutePath());
                }

                //递归跳出来的时候删除空文件夹
                logger.info("正在删除文件夹" + file.getAbsolutePath());
                file.delete();
            }
        }
        return true;
    }

    /**
     * 修改文件路径
     * @param oldFilePath   原先的路径
     * @param newFilePath   新的路径
     * @throws Exception
     */
    private boolean moveDataFile2Reject(String oldFilePath, String newFilePath) throws Exception {
        try {
            File newFile = new File(newFilePath);
            File oldFile = new File(oldFilePath);
            if(oldFile.isDirectory()){
                if(!newFile.exists()){
                    if(!newFile.mkdirs()){
                        return false;
                    }
                }
                File[] files = oldFile.listFiles();
                if(files.length >= 0){
                    for (File f : files) {
                        if(f.isFile()) {
                            f.renameTo(new File(newFile +"/"+ f.getName()));
                        }
                    }
                    oldFile.delete();
                }
                return true;
            } else if (oldFile.isFile()){
                return oldFile.renameTo(new File(newFilePath));
            }
        }catch (Exception e){
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 获取该目录文件
     * @param fid
     * @param userId
     * @param type
     * @return
     */
    @ApiOperation(value = "获取该路径下的所有对象", notes = "获取对应用户该路径下的所有对象")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fid", value = "文件或文件夹的id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "type", value = "用户路径类型", required = true, dataType = "Integer")
    })
    @RequestMapping(value = "getFile", method = RequestMethod.POST)
    @Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResponseMessage getFileInfoList(@RequestParam(value = "fid") String fid,
                                           @RequestParam(value = "userId") String userId,
                                           @RequestParam(value = "type") Integer type) {
        List<Map> maps = new ArrayList<>();
        List<FileType> file = getFilePath(userId,fid,type);
        if (file!=null){
            FileType fileType = getOnePid(userId,fid,type);
            String pid ;
            if (fileType==null){
                pid = "0";
            }else {
                pid = fileType.getPid();
            }
            for (FileType f : file){
                String filePath =  f.getFilePath();
                List<Question> questions = getFileType(userId,filePath);
                if (questions!=null){
                    for (Question question : questions){
                        Map<String,Object> map = new HashMap<>();
                        map.put("fid",f.getId());
                        map.put("filePath",f.getFilePath());
                        map.put("fileType",f.getType());  //经典练习
                        map.put("pid",pid);
                        map.put("queType",question.getQuestionFileType()); //word 、pdf
                        map.put("queName",question.getQuestionName());
                        map.put("queId",question.getId());
                        map.put("queTime",question.getQuestionTime());
                        map.put("doNumber",question.getDoNumber());
                        maps.add(map);
                    }

                }else {
//                map.put("queType","5");
                    return ResponseMessage.fail(maps);
                }
            }
            if (maps!=null){
                return ResponseMessage.success(maps);
            }else {
                return ResponseMessage.fail(maps);
            }

        }else {
            return ResponseMessage.fail(maps);
        }
    }

    public List<Question> getFileType(String userId , String filePath){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("filePath",filePath);
        List<Question> question = questionService.list(queryWrapper);

        return question;
    }

    /**
     * 从当前页面获取父页面
     * @param userId
     * @param fid
     * @return
     */
    public List<FileType> getFilePath(String userId, String fid,Integer fileType){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("pid",fid);
        queryWrapper.eq("type",fileType);
        List<FileType> fileTypes = fileTypeService.list(queryWrapper);
        return fileTypes;
    }

    /**
     * 传递这个目录的父id
     * @param userId
     * @param fid
     * @param type
     * @return
     */
    public FileType getOnePid(String userId, String fid,Integer type){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("id",fid);
        queryWrapper.eq("type",type);
        FileType fileType = fileTypeService.getOne(queryWrapper);
        return fileType;

    }

    @ApiOperation(value = "获取该fid的pid", notes = "获取对应用户该路径下的所有对象")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fid", value = "文件或文件夹的id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "type", value = "用户路径类型", required = true, dataType = "Integer")
    })
    @RequestMapping(value = "getPid", method = RequestMethod.POST)
    @Transactional(isolation= Isolation.DEFAULT,propagation= Propagation.REQUIRED,rollbackFor = Exception.class)
    public ResponseMessage getPid(@RequestParam(value = "fid") String fid,
                                           @RequestParam(value = "userId") String userId,
                                           @RequestParam(value = "type") Integer type) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("userId",userId);
        queryWrapper.eq("id",fid);
        queryWrapper.eq("type",type);
        FileType fileType = fileTypeService.getOne(queryWrapper);
        if (fileType!=null&&!fileType.equals("")){
            return ResponseMessage.success(fileType.getPid());
        }else {
            return ResponseMessage.fail("没有找到上一层路径");
        }

    }
}
